/*
this file uses the main functions of the IAX library to make calls and register with Asterisk

the program takes as input information form the user
	- the IP address of the peer to call
	- and the name of the user
	- and the number that the user would want to see appear on the callee's end. 

it establishes a call.
*/

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<string.h>
#include<ctype.h>
#include "iaxclient.h"

#define MAX_DATE 24

int initialized = 0;
int reg_id = 0;
static char *output_timestp = "start";


//returns the current time stamp
char *  get_date (char * pDate){

        time_t now;
        char the_date[MAX_DATE];

        the_date[0]='\0';
        now = time(NULL);

        if(now != -1){
                strftime(the_date, MAX_DATE, "%d_%m_%Y_%I_%M_%S", gmtime(&now));
        }

        pDate = (char *) calloc(MAX_DATE,sizeof (char));

return strncpy(pDate, the_date, (MAX_DATE -1));
}


void printOptionsMenu(){
	printf("enter:\n a: to answer a call\n t: to terminate a call\n q: to quit\n c  call a peer\n r: to register with astersik\n p: print list of audio devices\n h: for the menu\n");
}

int netstat_callback(struct iaxc_ev_netstats n) {
    static int i;

//write the values of the netstat event into the log file
	FILE * outputFile = NULL;
	
	outputFile = fopen(output_timestp, "a+");

    //prints the header after every 15 netstat event
  /*  if(i++%15 == 00)
	fprintf(outputFile, "RTT\t"
	    "Rjit\tRlos%%\tRlosC\tRpkts\tRdel\tRdrop\tRooo\t"
	    "Ljit\tLlos%%\tLlosC\tLpkts\tLdel\tLdrop\tLooo\n"
	    );
*/
    fprintf(outputFile, "%d\t"
	  "%d\t%d\t%d\t%d\t%d\t%d\t%d\t"
	  "%d\t%d\t%d\t%d\t%d\t%d\t%d\n",

	    n.rtt,

	    n.remote.jitter,
	    n.remote.losspct,
	    n.remote.losscnt,
	    n.remote.packets,
	    n.remote.delay,
	    n.remote.dropped,
	    n.remote.ooo,

	    n.local.jitter,
	    n.local.losspct,
	    n.local.losscnt,
	    n.local.packets,
	    n.local.delay,
	    n.local.dropped,
	    n.local.ooo
    );
fclose(outputFile);
    return 0;
}



void printEndOfCommand(){
 printf("****************************\n");
}

int call_received_event(struct iaxc_ev_call_state incomingCall){
    if((incomingCall.state & IAXC_CALL_STATE_RINGING))
    {
		printf("Receiving Incoming Call Request...\n");
    }
    return 0;
}

int events_callback(iaxc_event e)
{
    switch(e.type) {
        case IAXC_EVENT_STATE:
            return call_received_event(e.ev.call);
        case IAXC_EVENT_NETSTAT:
            return netstat_callback(e.ev.netstats);
        default:
            return 0;  // not handled
    }
}

void stopSession(){

      if(initialized){
	//dumps all the calls
	//frees the data structure of calls
	iaxc_shutdown();
        initialized = 0;
	}
      if(reg_id){
	//unregisters the user using the registration id. 
	iaxc_unregister(reg_id);
	
        reg_id=0;	
        }

}

void stopProgram(int signalNumber){
	if(signalNumber==SIGINT || signalNumber==SIGTERM){
		stopSession();
                exit(0);
	}
}

void fatal_error(char * errorMessage){
	printf("%s\n", errorMessage);
		stopSession();
		exit(0);
}

void list_devices()
{
    struct iaxc_audio_device *devs;
    int nDevs, input, output, ring;
    int i;

    iaxc_audio_devices_get(&devs,&nDevs, &input, &output, &ring);
    for(i=0;i<nDevs;i++) {
	fprintf(stderr, "DEVICE ID=%d NAME=%s CAPS=%lx\n", devs[i].devID, devs[i].name, devs[i].capabilities);
    }
}


int main(int argc, char **argv)
{

int initResult=0;
char * silenceThresh =argv[1];
char * destIP= NULL;
char * astHost; char * astUser; char * astPwd;
char c;
char * the_date;

	//the argument that is passed is the ip address of the callee
	//printf("%s\n", destIP);

	//call the function stopSession to do some cleanup when the program exits
	atexit(stopSession);

	/* set signal handler so that the CRTL-Cs is handled */
	//	
	signal(SIGINT, stopProgram);
	signal(SIGTERM, stopProgram);

	//initialize the iaxclient
	/*
	- takes as argument the max number of calls to be handled at once 
	the following actions are performed:
	   - set jitter buffer output
	   - sets the audio preferences:
           - set receive/send networking functions 
           - sets the UDP port that will be used for communication
	   - Sets the max number of calls
           - Initializes the Calls array of size [maxcalls] 
           - sets the caller id and number for every call in the array
	   - sets selected_call which identifies the current call handled to -1
           - determines whether to use alsa or portaudio for the initializaiton of the audio devices.
           - initializes the video devices if used
           - sets the audio codecs to be used (ULAW, SPEEX, GSM)
           
*/

	//if an error arises exit the program
	initResult = iaxc_initialize(1);
	printf("initResutl:%d\n", initResult);

	if(initResult)
		fatal_error("error while initializing the iaxclient");

	//set the format format for the codec
	iaxc_set_formats(IAXC_FORMAT_SPEEX,IAXC_FORMAT_SPEEX);	

	iaxc_input_level_set(3);

	iaxc_set_event_callback( events_callback);

	if(silenceThresh) {
	    //fprintf( "Calling %s\n", destIP);

	   	iaxc_set_silence_threshold(atof(silenceThresh));
	   
	} 

	 printOptionsMenu();

	iaxc_start_processing_thread();
	
	
	while((c = getc(stdin))){
		switch (tolower(c)){
			case 'a':
				//answer incoming call
				//get the timeStamp of the call
				//the_date is empty char *
				output_timestp = get_date(the_date);
				iaxc_select_call(0);
				break;
			case 'c':
				printf("enter IP address of peer:");
				destIP = (char * )malloc(16);
				scanf("%s", destIP);
				printf("calling %s...\n", destIP);
				output_timestp = get_date(the_date);
				iaxc_call(destIP);
				break;
			case 'h':
				printOptionsMenu();
				break;
			case 'p':
				//list the devices that can be used on that machine
				list_devices();
				break;
			case 'q':
				printf("Hang up and exit\n");
				iaxc_dump_call();
				iaxc_millisleep(1000);
				iaxc_stop_processing_thread();
				exit(0);
				break;
			case 'r':
				printf("Asterisk host ip address:");
				astHost = (char * )malloc(16);
				scanf("%s", astHost);
								
				printf("Asterisk username:");
				astUser = (char * )malloc(40);
				scanf("%s", astUser);

				printf("Asterisk password:");
				astPwd = (char * )malloc(30);
				scanf("%s", astPwd);

				reg_id = iaxc_register(astUser, astPwd, astHost);
				printf("registered. Session id %d\n", reg_id);
				break;
			case 't':
				iaxc_dump_call();
				printf("call terminated");
				break;
			default:
				break;
			}	
			printEndOfCommand();
		}
	
}
